package com.swordget.service.impl;

import com.swordget.commons.ColumnDesignCompareConstant;
import com.swordget.commons.ColumnType;
import com.swordget.entity.ColumnDesign;
import com.swordget.entity.bo.ColMetadata;
import com.swordget.service.ColumnDesignCompareService;
import com.swordget.service.VerifyColumnService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ColumnDesignCompareServiceImpl implements ColumnDesignCompareService {

    @Autowired
    private VerifyColumnService verifyColumnService;

    @Override
    public Map<String, List<ColMetadata>> compare(List<ColumnDesign> columnDesigns, List<ColumnDesign> dbColumnDesigns) {
        Map<String, List<ColMetadata>> compareResult = new HashMap<>();
        List<ColMetadata> addCols = new ArrayList<>();
        List<ColMetadata> updateCols = new ArrayList<>();
        List<ColMetadata> delCols = new ArrayList<>();
        List<ColMetadata> commentCols = new ArrayList<>();
        //1.新增字段处理
        columnDesigns.forEach(columnDesign -> {
            if (StringUtils.isBlank(columnDesign.getSerialNo())) {
                ColMetadata addDolMetadata = new ColMetadata();
                addDolMetadata.setName(columnDesign.getName())
                        .setType(columnDesign.getType())
                        .setWidth(columnDesign.getWidth())
                        .setPoint(columnDesign.getPoint())
                        .setNotNull("Y".equals(columnDesign.getNotNull()) ? "NOT NULL" : "")
                        .setComment(columnDesign.getComment());
                addCols.add(addDolMetadata);
                if (StringUtils.isNotBlank(columnDesign.getComment())) {
                    commentCols.add(addDolMetadata);
                }
            }
        });
        Map<String, ColumnDesign> columnDesignMap = toColumnDesignMap(columnDesigns);
        Map<String, ColumnDesign> dbColumnDesignMap = toDbColumnDesignMap(dbColumnDesigns);
        //2.删除字段处理
        dbColumnDesigns.forEach(dbColumnDesign -> {
            ColumnDesign col = columnDesignMap.get(dbColumnDesign.getSerialNo());
            if (Objects.isNull(col)) {
                ColMetadata delDelMetadata = new ColMetadata();
                delDelMetadata.setOriginalName(dbColumnDesign.getName());
                delCols.add(delDelMetadata);
            }
        });
        //3.修改字段处理
        for (ColumnDesign columnDesign : columnDesigns) {
            ColumnDesign col = dbColumnDesignMap.get(columnDesign.getSerialNo());
            if (Objects.isNull(col)) {
                continue;
            }
            if (needUpdate(columnDesign, col)) {
                verifyColumnService.verifyColumnByUpdate(col, columnDesign);
                ColMetadata updateDelMetadata = new ColMetadata();
                updateDelMetadata.setName(columnDesign.getName())
                        .setType(columnDesign.getType())
                        .setWidth(columnDesign.getWidth())
                        .setPoint(columnDesign.getPoint())
                        .setOriginalName(col.getName())
                        .setNotNull("Y".equals(columnDesign.getNotNull()) ? "NOT NULL" : "")
                        .setComment(columnDesign.getComment());
                updateCols.add(updateDelMetadata);
            }
            if (StringUtils.isBlank(col.getComment()) && StringUtils.isBlank(columnDesign.getComment())) {
                continue;
            }
            ColMetadata updateCommentMetadata = new ColMetadata();
            updateCommentMetadata.setComment(columnDesign.getComment()).setName(columnDesign.getName());
            commentCols.add(updateCommentMetadata);
        }
        compareResult.put(ColumnDesignCompareConstant.TYPE_ADD, addCols);
        compareResult.put(ColumnDesignCompareConstant.TYPE_UPDATE, updateCols);
        compareResult.put(ColumnDesignCompareConstant.TYPE_DEL, delCols);
        compareResult.put(ColumnDesignCompareConstant.TYPE_COMMENT, commentCols);
        return compareResult;
    }

    private boolean needUpdate(ColumnDesign columnDesign, ColumnDesign col) {
        boolean nameNotEqual = !(columnDesign.getName().toLowerCase().equals(col.getName().toLowerCase()));
        boolean widthNotEqual = columnDesign.getWidth() != col.getWidth();
        boolean typeNotEqual = !(columnDesign.getType().toLowerCase().equals(col.getType().toLowerCase()));
        boolean baseR = nameNotEqual || widthNotEqual || typeNotEqual;
        if (ColumnType.NUMBER.equals(columnDesign.getType()) && (columnDesign.getPoint() != col.getPoint())) {
            return true;
        }
        return baseR;
    }

    private Map<String, ColumnDesign> toDbColumnDesignMap(List<ColumnDesign> dbColumnDesigns) {
        Map<String, ColumnDesign> columnDesignMap = new HashMap<>();
        dbColumnDesigns.forEach(dbColumnDesign -> {
            columnDesignMap.put(dbColumnDesign.getSerialNo(), dbColumnDesign);
        });
        return columnDesignMap;
    }

    private Map<String, ColumnDesign> toColumnDesignMap(List<ColumnDesign> columnDesigns) {
        Map<String, ColumnDesign> columnDesignMap = new HashMap<>();
        columnDesigns.forEach(columnDesign -> {
            if (StringUtils.isNotBlank(columnDesign.getSerialNo())) {
                columnDesignMap.put(columnDesign.getSerialNo(), columnDesign);
            }
        });
        return columnDesignMap;
    }
}